package com.ruoyi.system.habit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.domain.WrapperResponse;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.system.habit.domain.entity.ClockinRecord;
import com.ruoyi.system.habit.domain.entity.TomatoRecord;
import com.ruoyi.system.habit.domain.entity.User;
import com.ruoyi.system.habit.mapper.ClockInRecordMapper;
import com.ruoyi.system.habit.mapper.HabitMapper;
import com.ruoyi.system.habit.mapper.TomatoRecordMapper;
import com.ruoyi.system.habit.mapper.UserMapper;
import com.ruoyi.system.habit.service.StatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: xujiabing
 * @date: 2024-10-23 16:22
 * @description: 统计分析实现
 */
@Service
@DataSource(DataSourceType.SLAVE)
public class StatServiceImpl implements StatService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ClockInRecordMapper clockInRecordMapper;
    @Autowired
    private HabitMapper habitMapper;
    @Autowired
    private TomatoRecordMapper tomatoRecordMapper;

    /**
     * 查询用户总数
     * @return
     */
    @Override
    public Long queryUserTotals() {
        return userMapper.selectCount(null);
    }

    /**
     * 查询打卡总数
     * @return
     */
    @Override
    public Long queryCheckInTotals() {
        return clockInRecordMapper.selectCount(null);
    }

    /**
     * 查询今日打卡数
     * @return
     */
    @Override
    public Long queryCheckInToday() {
        return clockInRecordMapper.
                selectCount(new LambdaQueryWrapper<ClockinRecord>().
                        eq(ClockinRecord::getClockinTime,new Date()));
    }

    /**
     * 查询今日打卡-用户数量
     * @return
     */
    @Override
    public Long queryUserCheckInToday() {
        // 获取今天的日期，并转换为 Date 对象
        LocalDate today = LocalDate.now();
        Date startOfDay = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date endOfDay = Date.from(today.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());

        //查询今日打卡记录
        List<ClockinRecord> list = clockInRecordMapper.
                selectList(new LambdaQueryWrapper<ClockinRecord>()
                        .ge(ClockinRecord::getClockinTime, startOfDay)
                        .le(ClockinRecord::getClockinTime, endOfDay));

        //流式处理得到去重用户数
        List<Integer> collect = list
                .stream()
                .map(ClockinRecord::getUid)
                .distinct() //用户id去重
                .collect(Collectors.toList());
        return (long) collect.size();
    }

    /**
     * 查询习惯总数
     * @return
     */
    @Override
    public Long queryHabitsTotals() {
        return habitMapper.selectCount(null);
    }

    /**
     * 查询番茄时钟累加
     * @return
     */
    @Override
    public Long queryTomatoTimesTotals() {
        List<TomatoRecord> records = tomatoRecordMapper.selectList(null);
        int sum = records
                .stream()
                .mapToInt(TomatoRecord::getTimeLong)
                .sum();
        return (long) sum;
    }

    /**
     * 今日番茄总时长
     * @return
     */
    @Override
    public Long queryTomatoToday() {
        // 获取今天的日期，并转换为 Date 对象
        LocalDate today = LocalDate.now();
        Date startOfDay = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date endOfDay = Date.from(today.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
        //日期筛选
        List<TomatoRecord> records = tomatoRecordMapper.selectList(
                new LambdaQueryWrapper<TomatoRecord>()
                        .ge(TomatoRecord::getFinishTime,startOfDay)
                        .le(TomatoRecord::getFinishTime,endOfDay));
        //stteam 获取番茄时间总和
        int sum = records.stream()
                .mapToInt(TomatoRecord::getTimeLong)
                .sum();
        return (long) sum;
    }
}
